package com.yzpass.api.user.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yzpass.api.common.FilterDTO;
import com.yzpass.api.common.IdName;
import com.yzpass.api.common.OffsetPage;
import com.yzpass.api.common.Result;
import com.yzpass.api.common.cache.ICache;
import com.yzpass.api.security.UserPermissionService;
import com.yzpass.api.user.dto.ResDTO;
import com.yzpass.api.user.dto.RoleDTO;
import com.yzpass.api.user.entity.Role;
import com.yzpass.api.user.entity.RoleRes;
import com.yzpass.api.user.mapper.RoleMapper;
import com.yzpass.api.user.mapper.RoleResMapper;
import io.micrometer.common.util.StringUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;
import java.util.UUID;

@Service
public class RoleService {

    @Resource
    RoleMapper roleMapper;
    @Resource
    RoleResMapper roleResMapper;

    @Resource
    LoginService loginService;

    @Resource
    UserPermissionService userPermissionService;
    @Resource
    ICache iCache;

    public Result<List<RoleDTO>> list(@RequestBody FilterDTO input)  {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(input.getKeyword())){
            String keyword = input.getKeyword();
            queryWrapper.nested(c-> c.like(Role::getRoleName,keyword)
                    .or().like(Role::getNote,keyword));
        }

        queryWrapper.orderByAsc(Role::getRoleName);
        OffsetPage<Role> p = new OffsetPage<>(input.getOffset(),input.getSize());
        IPage<Role> iPage =  roleMapper.selectPage(p,queryWrapper);
        List<RoleDTO> list = iPage.getRecords().stream().map(RoleDTO::fromRole).toList();
        return Result.success(list,iPage.getTotal());
    }

    public Result delete(String id) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getRoleId,UUID.fromString(id));
        roleMapper.delete(queryWrapper);
        return Result.success();
    }

    @Transactional
    public Result<RoleDTO> save(RoleDTO input) {
        Role dbRole = roleMapper.selectById(input.getRoleId());
        Role inputRole = input.toRole();
        iCache.remove(userPermissionService.roleResKey(inputRole.getRoleId()));
        if(dbRole==null){
            roleMapper.insert(inputRole);
        }else{
            roleMapper.updateById(inputRole);
        }

        LambdaQueryWrapper<RoleRes> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleRes::getRoleId,inputRole.getRoleId());
        roleResMapper.delete(queryWrapper);

        if(!CollectionUtils.isEmpty(input.getResArr())){
            List<RoleRes> resList = input.getResArr().stream()
                    .map(t->t.toRoleRes(inputRole.getRoleId())).toList();
            roleResMapper.insert(resList);
        }
        return view(input.getRoleId());
    }

    public Result<RoleDTO> view(String id) {
        Role role = roleMapper.selectById(id);
        RoleDTO dto = RoleDTO.fromRole(role);

        LambdaQueryWrapper<RoleRes> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleRes::getRoleId,role.getRoleId());
        List<RoleRes> list = roleResMapper.selectList(queryWrapper);
        if(list!=null){
            List<ResDTO> resArr = list.stream().map(ResDTO::from).toList();
            dto.setResArr(resArr);
        }

        return Result.success(dto);
    }

    public Result<List<IdName>> simpleList() {
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        List<Role> list = roleMapper.selectList(wrapper);
        List<IdName> resList = list.stream().map(t-> new IdName(t.getRoleId().toString(),t.getRoleName())).toList();
        return Result.success(resList,(long)resList.size());
    }
}
